package com.kly.user.serviceImpl;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.nacos.api.config.annotation.NacosValue;
import com.fqgj.common.utils.StringUtils;
import com.fqgj.log.util.UUID;
import com.kly.user.config.UploadUserDto;
import com.kly.user.constant.ConstantType;
import com.kly.user.db.dao.InterestDao;
import com.kly.user.db.dao.UserAccountsDao;
import com.kly.user.db.dao.UserAlbumsContentDao;
import com.kly.user.db.dao.UserAlbumsDao;
import com.kly.user.db.dao.UserDao;
import com.kly.user.db.dao.UserInterestsDao;
import com.kly.user.db.dao.UserProfileDao;
import com.kly.user.db.entity.InterestEntity;
import com.kly.user.db.entity.UserAccountsEntity;
import com.kly.user.db.entity.UserAlbumsContentEntity;
import com.kly.user.db.entity.UserAlbumsEntity;
import com.kly.user.db.entity.UserEntity;
import com.kly.user.db.entity.UserInterestsEntity;
import com.kly.user.db.entity.UserProfileEntity;
import com.kly.user.enums.ImageType;
import com.kly.user.enums.UserStatus;
import com.kly.user.enums.UserType;
import com.kly.user.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.util.*;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

@Service("uploadUserService")
public class UploadUserService {

    @Autowired
    UserDao userDao;
    @Autowired
    UserAccountsDao userAccountsDao;

    @Autowired
    UserAlbumsDao userAlbumsDao;

    @Autowired
    UserAlbumsContentDao userAlbumsContentDao;

    @Autowired
    UserProfileDao userProfileDao;

    @Autowired
    InterestDao interestDao;

    @Autowired
    UserInterestsDao userInterestsDao;


    public static final String STORAGE_DIRECTORY = "/images/";

    /**
     * 存储介质：aws/cloudStorage
     */
    @NacosValue(value = "${storageType}", autoRefreshed = true)
    private String storageType;


    //    @Transactional(rollbackFor = Exception.class)
    public void UploadUser(String fileName, String fileNames) {
        int corePoolSize = 10;
        int maximumPoolSize = 20;
        long keepAliveTime = 60L;
        BlockingQueue<Runnable> queue = new LinkedBlockingQueue<>(10);

        ThreadPoolExecutor executor = new ThreadPoolExecutor(corePoolSize, maximumPoolSize,
                keepAliveTime, TimeUnit.SECONDS, queue, new ThreadPoolExecutor.CallerRunsPolicy());

        List<InterestEntity> interestEntities = interestDao.selectByParams(new HashMap<>());
        Map<String, InterestEntity> interestMap = UserUtil.listToMap(interestEntities, item -> String.valueOf(item.getInterestName()));
        EasyExcel.read(fileName)
                .sheet(0)
                .head(UploadUserDto.class)
                .registerReadListener(new AnalysisEventListener<UploadUserDto>() {
                    @Override
                    public void invoke(UploadUserDto data, AnalysisContext context) {
                        executor.execute(() -> UploadUser(data, fileNames, interestMap));
                    }

                    @Override
                    public void doAfterAllAnalysed(AnalysisContext context) {
                        executor.shutdown();
                    }
                })
                .doRead();
    }

    public void UploadUser(UploadUserDto userDto, String fileNames, Map<String, InterestEntity> interestMap) {

        String avatarUrl = null;
        String userCode = String.valueOf(UserSnowflake.getInstance().nextId());

        String albumCode = String.valueOf(OtherSnowflake.getInstance().nextId());
        //插入用户公开相册
        UserAlbumsEntity userAlbumsEntity = new UserAlbumsEntity();
        userAlbumsEntity.setUserCode(userCode);
        userAlbumsEntity.setAlbumCode(albumCode);
        userAlbumsEntity.setStatus(ConstantType.ALBUM_STATUS);
        userAlbumsEntity.setType(ConstantType.PUBLIC_PHOTO);
        userAlbumsDao.insert(userAlbumsEntity);


        File directory = new File(fileNames + File.separator + userDto.getId());
        if (directory.exists() && directory.isDirectory()) {
            File[] files = directory.listFiles();
            assert files != null;
            List<UserAlbumsContentEntity> albumsContents = new ArrayList<>();
            for (File file : files) {
                UserAlbumsContentEntity userAlbumsContent = new UserAlbumsContentEntity();
                if (isImageFile(file, userAlbumsContent) || isVideoFile(file, userAlbumsContent)) {
                    int lastIndexOfDot = file.getName().lastIndexOf(".");
                    String extensionName;
                    if (lastIndexOfDot == -1) {
                        return; // 没有扩展名
                    } else {
                        extensionName = "." + file.getName().substring(lastIndexOfDot + 1);
                    }
                    String fileName = STORAGE_DIRECTORY + UUID.getId() + extensionName;
                    if (avatarUrl == null) {
                        avatarUrl = fileName;
                    }
                    InputStream inputStream;
                    try {
                        if (storageType.equalsIgnoreCase("awsStorage")) {
                            inputStream = Files.newInputStream(file.toPath());
                            AwsStorageUtil.uploadFile(AwsStorageUtil.s3BucketName, inputStream, file.length(),
                                    fileName);
                        } else if (storageType.equalsIgnoreCase("cloudStorage")) {
                            GoogleStorageUtil.uploadObject(fileName, file.getPath());
                        }
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }

                    userAlbumsContent.setImageCode(String.valueOf(OtherSnowflake.getInstance().nextId()));
                    userAlbumsContent.setImageUrl(fileName);
                    userAlbumsContent.setAlbumCode(albumCode);
                    userAlbumsContent.setStatus(ConstantType.ALBUM_STATUS);
                    userAlbumsContent.setAlbumType(userAlbumsEntity.getType());
                    albumsContents.add(userAlbumsContent);

                }
            }

            userAlbumsContentDao.batchInsert(albumsContents);
            albumsContents.clear();


            //插入用户账户
            UserAccountsEntity userAccounts = new UserAccountsEntity();
            userAccounts.setUserCode(userCode);
            userAccounts.setAccount(String.valueOf(UUID.getId()));
            userAccounts.setAccountType(2);
            userAccountsDao.insert(userAccounts);

            UserProfileEntity userProfile = new UserProfileEntity();
            userProfile.setUserCode(userCode);
            if (StringUtils.isNotEmpty(userDto.getAboutMe())) {
                userProfile.setAboutMe(userDto.getAboutMe());
            } else {
                userProfile.setAboutMe("The man was lazy and left nothing behind");
            }

            userProfileDao.insert(userProfile);

            //插入用户信息
            UserEntity user = new UserEntity();
            user.setUserCode(userCode);
            user.setNickName(userDto.getNickName());
            if (userDto.getGender() == null) {
                user.setGender(0);
            } else if (userDto.getGender().equals("男")) {
                user.setGender(1);
            } else {
                user.setGender(2);
            }
            if (userDto.getLookingFor() == null) {
                user.setLookingFor(0);
            } else if (userDto.getLookingFor().equals("男")) {
                user.setLookingFor(1);
            } else {
                user.setLookingFor(2);
            }
            user.setAvatarUrl(avatarUrl);
            if (userDto.getInterests() != null) {
                List<UserInterestsEntity> interestsList = new ArrayList<>();
                String[] Interests = userDto.getInterests().split("\n");

                for (String str : Interests) {
                    if (interestMap.get(str) != null) {
                        UserInterestsEntity userInterest = new UserInterestsEntity();
                        userInterest.setUserCode(userCode);
                        userInterest.setInterestCode(String.valueOf(interestMap.get(str).getId()));
                        userInterest.setInterest(str);
                        interestsList.add(userInterest);
                    }
                }
                userInterestsDao.batchInsert(interestsList);
                interestsList.clear();
            }

            user.setBirthday(userDto.getBirthday());
            user.setStatus(UserStatus.ACTIVE.getType());
            if (Objects.isNull(user.getRegisterDate())) {
                user.setRegisterDate(new Date());
            }
            user.setUserType(UserType.MODEL.getType());
            userDao.insert(user);
        }
    }


    // 判断是否为视频文件
    public static boolean isVideoFile(File file, UserAlbumsContentEntity userAlbumsContent) {
        String[] videoExtensions = {".mp4", ".avi", ".mov", ".wmv", ".flv", ".mkv", ".mpeg", ".3gp", ".webm"};
        String fileName = file.getName().toLowerCase();

        for (String extension : videoExtensions) {
            if (fileName.endsWith(extension)) {
                userAlbumsContent.setType(ImageType.VIDEO.getType());
                return true;
            }
        }

        return false;
    }

    // 判断是否为图片文件
    public static boolean isImageFile(File file, UserAlbumsContentEntity userAlbumsContent) {
        String[] imageExtensions = {".jpg", ".gif", ".png", ".ico", ".bmp", ".jpeg"};
        String fileName = file.getName().toLowerCase();

        for (String extension : imageExtensions) {
            if (fileName.endsWith(extension)) {
                userAlbumsContent.setType(ImageType.IMAGE.getType());
                return true;
            }
        }

        return false;
    }

    public static void main(String[] args) {

        String fileName = "D:\\workFile\\dateFile\\50-Model-man\\Mode-man.xlsx";

        String fileNames = "D:\\workFile\\dateFile\\50-Model-man";

        List<UploadUserDto> dataList = new ArrayList<>();

        EasyExcel.read(fileName)
                .sheet(0)
                .head(UploadUserDto.class)
                .registerReadListener(new AnalysisEventListener<UploadUserDto>() {
                    @Override
                    public void invoke(UploadUserDto data, AnalysisContext context) {
                        dataList.add(data); // 将每行数据添加到对象列表中
                    }

                    @Override
                    public void doAfterAllAnalysed(AnalysisContext context) {
                        Set<String> stringSet = new HashSet<>();
                        for (int i = 1; i <= dataList.size(); i++) {
                            String userCode = String.valueOf(UserSnowflake.getInstance().nextId());

                            String jsonString = JSONObject.toJSONString(dataList.get(i - 1));
                            List<String> list = Arrays.asList(dataList.get(i - 1).getInterests().split("\n"));


                            for (String str : list) {
                                String trim = str.trim();
                                stringSet.add(trim);
                            }


                        }

                        System.out.println(stringSet);
                        // 读取完成后的操作，可在此处进行数据库写入操作
                    }
                })
                        .

                doRead();


    }


    public void copyFile(List<UploadUserDto> dataList, String fileNames) {
        for (int i = 1; i <= dataList.size(); i++) {
            List<File> folders = new ArrayList<>();
            File directory = new File(fileNames + "\\" + i);
            if (directory.exists() && directory.isDirectory()) {
                File[] files = directory.listFiles();
                assert files != null;
                File outputFiles = new File("D:\\workFile\\dateFile\\copyFile" + "\\copy" + i);
                for (File file : files) {
                    File outputFile = new File("D:\\workFile\\dateFile\\copyFile" + "\\" + i + "\\" + file.getName());
                    outputFile.getParentFile().mkdirs();
                    if (file.getName().indexOf(".jpg") > 0 || file.getName().indexOf(".gif") > 0
                            || file.getName().indexOf(".png") > 0 || file.getName().indexOf(".ico") > 0
                            || file.getName().indexOf(".bmp") > 0
                            || file.getName().indexOf(".jpeg") > 0) {
                        System.out.println(file.getName());
                        InputStream inputStream = null;
                        OutputStream outputStream = null;

                        try {
                            inputStream = Files.newInputStream(file.toPath());

                            outputStream = Files.newOutputStream(outputFile.toPath());

                            byte[] buffer = new byte[1024];
                            int length;

                            // 将输入流读入缓冲区，然后写入输出流
                            while ((length = inputStream.read(buffer)) != -1) {
                                outputStream.write(buffer, 0, length);
                            }
                        } catch (IOException e) {
                            e.printStackTrace();
                        } finally {
                            // 关闭输入输出流
                            try {
                                if (inputStream != null) {
                                    inputStream.close();
                                }
                                if (outputStream != null) {
                                    outputStream.close();
                                }
                            } catch (IOException e) {
                                e.printStackTrace();
                            }
                        }
                    }

                }
                System.out.println("---------分割线---------");
            }

        }
    }

}
